import 'dart:async';
import 'dart:io';
import 'dart:typed_data';
import 'dart:ui' as ui;

import 'package:camera/camera.dart';
import 'package:dio/dio.dart' as DIO;
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:google_mlkit_face_detection/google_mlkit_face_detection.dart';
import 'package:image/image.dart' as Img;
import 'package:path_provider/path_provider.dart';
import 'package:permission_handler/permission_handler.dart';

import '../net/dio_utils.dart';
import '../page/common/saveLoadingWidget.dart';
import '../utils/toast_utils.dart';
import 'detector_view.dart';
import 'face_detector_painter.dart';

class FaceDetectorView extends StatefulWidget {
  const FaceDetectorView({Key key}) : super(key: key);

  @override
  State<FaceDetectorView> createState() => _FaceDetectorViewState();
}

class _FaceDetectorViewState extends State<FaceDetectorView> {
  final FaceDetector _faceDetector = FaceDetector(
    options: FaceDetectorOptions(
      enableContours: true,
      enableLandmarks: true,
    ),
  );
  bool _canProcess = true;
  bool _isBusy = false;
  bool _isUpload = false;
  CustomPaint _customPaint;
  String _text;

  //摄像头
  var _cameraLensDirection = CameraLensDirection.front;

  bool reuestCameraPermission = true;
  bool cameraPermission = false;

  @override
  void initState() {
    super.initState();
    Future.delayed(Duration.zero, () {
      _initCamera();
    });
  }

  void _initCamera() async {
    if (Platform.isAndroid) {
      cameraPermission = await requestLocationPermission();
      reuestCameraPermission = false;
    } else {
      cameraPermission = true;
      reuestCameraPermission = false;
    }

    setState(() {});
  }

  @override
  void dispose() {
    _canProcess = false;
    _faceDetector.close();
    super.dispose();
  }

  /// 申请相机权限
  /// 授予定位权限返回true， 否则返回false
  Future<bool> requestLocationPermission() async {
    //获取当前的权限
    var status = await Permission.camera.status;
    if (status == PermissionStatus.granted) {
      //已经授权
      return true;
    } else {
      if (Platform.isAndroid) {
        dynamic press = await Get.defaultDialog(
            title: "温馨提示",
            middleText: "请允许APP访问您的相机权限来使用人脸识别功能",
            backgroundColor: Colors.white,
            titleStyle: const TextStyle(color: Colors.black),
            middleTextStyle: const TextStyle(color: Colors.red),
            textConfirm: "同意",
            textCancel: "不同意",
            confirmTextColor: Colors.white,
            onConfirm: () {
              Get.back(result: true);
            },
            onCancel: () {
              Get.back(result: false);
            },
            radius: 8);
        if (press == null || !press) {
          return false;
        }
      }

      //未授权则发起一次申请
      status = await Permission.camera.request();
      if (status == PermissionStatus.granted) {
        return true;
      } else {
        return false;
      }
    }
  }

  bool _submit = false;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SizedBox.expand(
        child: Stack(
          alignment: Alignment.center,
          children: [
            buildPositioned(),
            Positioned(
              child: Image.asset("assets/images/3.0x/face2.webp"),
              left: 0,
              right: 0,
              top: 0,
            ),
            Positioned(
              left: 0,
              right: 0,
              top: 140,
              child: Text(
                tipsMessage,
                textAlign: TextAlign.center,
              ),
            ),
            _isUpload
                ? Positioned.fill(
                    child: SaveLoadingWidget(
                      txt: "正在识别中.",
                    ),
                  )
                : SizedBox(),
            _backButton(),
          ],
        ),
      ),
    );
  }

  String tipsMessage = "请将人脸移动到框内";

  Widget buildPositioned() {
    if (!cameraPermission) {
      return Center(
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            Text("未授权摄像头权限"),
            SizedBox(
              height: 20,
            ),
            SizedBox(
              width: 120,
              height: 40,
              child: ElevatedButton(
                onPressed: () {
                  _initCamera();
                },
                child: Text("重新获取"),
              ),
            ),
            SizedBox(
              height: 20,
            ),
            SizedBox(
              width: 120,
              height: 40,
              child: ElevatedButton(
                onPressed: () {
                  Get.back();
                },
                child: Text("退出"),
              ),
            ),
          ],
        ),
      );
    }
    return Positioned.fill(
      child: DetectorView(
        title: 'Face Detector',
        customPaint: _customPaint,
        text: _text,
        onImage: _processImage,
        initialCameraLensDirection: _cameraLensDirection,
        onCameraLensDirectionChanged: (value) => _cameraLensDirection = value,
        onTakePicture: (XFile xfile) {
          //uploadImage(xfile);
        },
      ),
    );
  }

  Widget _backButton() => Positioned(
        bottom: 60,
        child: SizedBox(
          height: 50.0,
          width: 50.0,
          child: FloatingActionButton(
            heroTag: Object(),
            onPressed: () => Navigator.of(context).pop(),
            backgroundColor: Colors.black54,
            child: Icon(
              Icons.close,
              size: 20,
            ),
          ),
        ),
      );

  Widget buildLoadingWidget() {
    if (reuestCameraPermission) {
      return Positioned.fill(
        child: SaveLoadingWidget(
          txt: "相机权限请求中.",
        ),
      );
    }
    if (_isUpload) {
      return Positioned.fill(
        child: SaveLoadingWidget(
          txt: "正在识别中.",
        ),
      );
    }
    return SizedBox();
  }

  Future<void> _processImage(
      InputImage inputImage, CameraController controller) async {
    if (!mounted) {
      return;
    }
    String filePath = inputImage.filePath;
    Uint8List bytes = inputImage.bytes;
    print("生成 inputImage $filePath bytes:${bytes?.length}");

    if (!_canProcess) return;
    if (_isBusy) return;
    _isBusy = true;
    setState(() {
      _text = '';
    });
    final faces = await _faceDetector.processImage(inputImage);
    if (inputImage.metadata?.size != null &&
        inputImage.metadata?.rotation != null) {
      final painter = FaceDetectorPainter(
        faces,
        inputImage.metadata.size,
        inputImage.metadata.rotation,
        _cameraLensDirection,
      );
      _customPaint = CustomPaint(painter: painter);

      List<dynamic> points = [];
      //可用的人脸标志检测
      for (final Face face in faces) {
        for (final type in FaceLandmarkType.values) {
          final landmark = face.landmarks[type];
          if (landmark?.position != null) {
            print("人像特征 ${landmark?.position}");
            points.add(landmark.position);
          }
        }
      }
      if (points.length < 10) {
        await ToastUtils.showToast("请将人脸对准摄像头");
        _isBusy = false;
        if (mounted) {
          setState(() {});
        }
        return;
      }
      debugPrint("暂停预览回调");
      // controller.pausePreview();
      ///-------------------------------------------------------------------------------------------------------
      if (!_isUpload) {
        if (!mounted) {
          debugPrint("widget不可用 不执行操作");
          return;
        }
        tipsMessage = "正在分析中...";
        _isUpload = true;
        setState(() {});
        try {
          debugPrint("开始生成图像");
          XFile xFile = await controller.takePicture();
          debugPrint("开始压缩图片 ${xFile.path}");
          File file2 = await _compressImage(inputImage.metadata.size, xFile);
          debugPrint("开始上传图片 ${file2.path}");
          //上传图片
          dynamic result = await uploadImage(file2);
          if (result != null && result.toString().length > 0) {
            tipsMessage = "识别成功...";
            Get.back(result: result);
          } else {
            tipsMessage = "请将人脸移入框内...";
            _isUpload = false;
            setState(() {});
            // controller.resumePreview();
          }
        } catch (e) {
          debugPrint("上传图片失败 ${e.toString()}");
          ToastUtils.showToast("上传图片失败 ${e.toString()}");
        }
      } else {
        debugPrint("有正在上传的图片");
      }

      ///-------------------------------------------------------------------------------------------------------
    } else {
      String text = 'Faces found: ${faces.length}\n\n';
      for (final face in faces) {
        text += 'face: ${face.boundingBox}\n\n';
      }
      _text = text;
      // TODO: set _customPaint to draw boundingRect on top of image
      _customPaint = null;
    }
    _isBusy = false;
    if (mounted) {
      setState(() {});
    }
  }

  Future<File> _compressImage(Size size, XFile xFile) async {
    int width = size.width ~/ 2;
    int height = size.height ~/ 2;

    debugPrint("图像原尺寸 ${size.width}   ${size.height}  压缩后的尺寸 $width x $height");
    Img.Image image = Img.decodeImage(await xFile.readAsBytes());
    Img.Image resizedImage = Img.copyResize(image,
        width: height, height: width, maintainAspect: true);

    // 将调整大小的图像保存到临时文件
    String tempPath = (await getTemporaryDirectory()).path;
    File compressedImageFile = File('$tempPath/compressed_image.png');
    compressedImageFile.writeAsBytesSync(Img.encodeJpg(resizedImage));
    return compressedImageFile;
  }

  //将回调拿到的Uint8List格式的图片转换为File格式
  /// Uint8List 转 Image 方式一
  ui.Image _fun1(Uint8List list) {
    ui.Image image;
    ui.decodeImageFromList(list, (ui.Image callBack) {
      image = callBack;
    });
    return image;
  }

  /// Uint8List 转 Image 方式二
  Future<ui.Image> _fun2(Uint8List list) async {
    ui.Codec codec = await ui.instantiateImageCodec(list);
    ui.FrameInfo frame = await codec.getNextFrame();
    return frame.image;
  }

  //将回调拿到的Uint8List格式的图片转换为File格式
  SaveImage(Uint8List imageByte) async {}

  Future<String> uploadImage(File xfile) async {
    DIO.FormData formData = DIO.FormData.fromMap({
      "file": await DIO.MultipartFile.fromFile(xfile.path),
    });

    ResponseInfo responseInfo = await DioUtils.instance
        .postRequest(url: HttpHelper.uploadImageFlutter, formData: formData);
    if (responseInfo.success) {
      if (responseInfo.data != null &&
          responseInfo.data.toString().isNotEmpty) {
        ToastUtils.showToast("识别成功");
        // Future.delayed(Duration(milliseconds: 100), () {
        //   Get.back(result: responseInfo.data);
        // });
        return responseInfo.data;
      } else {
        debugPrint("图片上传信息异常 未获取到上传的图片");
        ToastUtils.showToast("图片上传信息异常 未获取到上传的图片");
      }
    } else {
      ToastUtils.showToast("图片上传信息异常 ${responseInfo.message}");
      debugPrint("图片上传信息异常 ${responseInfo.message}");
    }
    return "";
  }
}
